// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.

#include "StdAfx.h"
#include "QvXmlDocument.h"
#include "QvXmlNodeList.h"
#include "QvXmlNode.h"
#include <strsafe.h>

QvXmlNode::QvXmlNode(IXMLDOMNode* pNode) : QvObject(), 
    m_pChildNodes(NULL)
{
    //
    // Store the Node and take a reference to it
    //
    m_pNode = pNode;
    m_pNode->AddRef();
    m_strName = NULL;
    m_strText = NULL;
}

QvXmlNode::QvXmlNode(QvXmlNode const & obj)
{
    m_pNode = obj.m_pNode;
    if(m_pNode)
    {
        m_pNode->AddRef();
    }

    m_pChildNodes = obj.m_pChildNodes;
    if(m_pChildNodes)
    {
        m_pChildNodes->AddRef();
    }
    
    m_strName = NULL;
    m_strText = NULL;
}

QvXmlNode& QvXmlNode::operator=(QvXmlNode const & obj)
{
    if(m_strName)
    {
        ::SysFreeString(m_strName);
        m_strName = NULL;
    }
    if(m_strText)
    {
        ::SysFreeString(m_strText);
        m_strText = NULL;
    }
    if(m_pChildNodes)
    {
        m_pChildNodes->Release();
    }
    m_pChildNodes = obj.m_pChildNodes;
    if(m_pChildNodes)
    {
        m_pChildNodes->AddRef();
    }

    if(m_pNode)
    {
        m_pNode->Release();
    }
    m_pNode = obj.m_pNode;
    if(m_pNode)
    {
        m_pNode->AddRef();
    }
    return *this;
}

QvXmlNode::~QvXmlNode()
{
    if(NULL != m_pChildNodes)
    {
        m_pChildNodes->Release();
        m_pChildNodes = NULL;
    }
    if (NULL != m_pNode)
    {
        m_pNode->Release();
        m_pNode = NULL;
    }
    if(m_strName)
    {
        ::SysFreeString(m_strName);
        m_strName = NULL;
    }
    if(m_strText)
    {
        ::SysFreeString(m_strText);
        m_strText = NULL;
    }
}

QvXmlNodeList* QvXmlNode::GetChildNodes()
{
    if (NULL == m_pChildNodes && NULL != m_pNode)
    {
        HRESULT hr = S_OK;
        IXMLDOMNodeList* pChildNodes = NULL;

        hr = m_pNode->get_childNodes(&pChildNodes);
        if (SUCCEEDED(hr) && NULL != pChildNodes)
        {
            m_pChildNodes = new QvXmlNodeList(pChildNodes);

            pChildNodes->Release();
            pChildNodes = NULL;
        }
    }
    else if (NULL != m_pChildNodes)
    {
        m_pChildNodes->AddRef();
    }

    return m_pChildNodes;
}

const QvChar* QvXmlNode::GetName()
{
    if(m_strName)
    {
        ::SysFreeString(m_strName);
        m_strName = NULL;
    }
    if (NULL != m_pNode)
    {
        (void)m_pNode->get_nodeName(&m_strName);
    }
    return m_strName;
}

const QvChar* QvXmlNode::GetInnerText()
{
    if(m_strText)
    {
        ::SysFreeString(m_strText);
        m_strText = NULL;
    }
    if (NULL != m_pNode)
    {
        (void)m_pNode->get_text(&m_strText);
    }
    return m_strText;
}

